package com.jackrain.nea.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.jackrain.nea.config.PropertiesConf;
import com.jackrain.nea.ext.oss.OssHelper;
import com.jackrain.nea.ext.oss.OssResult;
import com.jackrain.nea.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


@RestController
@Api(value = "UploadController", description = "文件上传")
public class UploadController {

    @Autowired
    private PropertiesConf pconf;

    public static OssHelper ossHelper;
//    public static String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";

    @PostConstruct
    public void afterInit() {
        if (ossHelper == null) {
            String accessKeyId = pconf.getProperty("ons.accessKey");
            String accessKeySecret = pconf.getProperty("ons.secretKey");
            String bucketName = pconf.getProperty("oss.bucketName");
            String endpoint = pconf.getProperty("oss.endpoint");
            ossHelper = new OssHelper(accessKeyId, accessKeySecret, endpoint, bucketName);
        }

    }


    @RequestMapping(path = "/p/cs/upload", method = RequestMethod.POST)
    @ApiOperation(value = "文件上传", httpMethod = "POST")
    public JSONObject upload(@RequestParam(value = "path", required = true) String path,
                             @RequestParam(value = "file", required = true) MultipartFile file,
                             HttpServletRequest request, HttpSession session) throws Exception {
        ValueHolder vh = new ValueHolder();

        if (file == null || file.isEmpty()) {
            // 未选择文件
            vh.put("code", -1);
            vh.put("message", "未选择文件");
            return vh.toJSONObject();
        }

        try {
            // 文件原名称
            String fileName = file.getOriginalFilename();
            //小于1m的图片 直接上传
            OssResult result = file.getSize() < 1 * 1024 * 1024
                    ? ossHelper.upload(path, fileName, file.getBytes())
                    : ossHelper.SectionUpload(path, fileName, file.getInputStream(), 400, 5);

            if (result.isError()) {
                throw result.getException();
            }
            JSONObject data = new JSONObject();
            data.put("uploadId", result.getKey());
            data.put("url", result.getFullUrl());

            vh.put("code", 0);
            vh.put("data", data);
            vh.put("message", "Success");
        } catch (OSSException oe) {
            vh.put("code", -1);
            vh.put("message", "Error Code:" + oe.getErrorCode() +
                    " Request ID:      " + oe.getRequestId() +
                    " Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            vh.put("code", -1);
            vh.put("message", "Error Code:" + ce.getMessage());
        }

        return vh.toJSONObject();
    }

    @SuppressWarnings("Duplicates")
    @RequestMapping(path = "/p/cs/upload2", method = RequestMethod.POST)
    @ApiOperation(value = "文件上传", httpMethod = "POST")
    public JSONObject upload2(@RequestParam(value = "path", required = true) String path,
                              @RequestParam(value = "file", required = true) MultipartFile file,
                              HttpServletRequest request, HttpSession session) throws Exception {
        ValueHolder vh = new ValueHolder();

        if (file == null || file.isEmpty()) {
            // 未选择文件
            vh.put("code", -1);
            vh.put("message", "未选择文件");
            return vh.toJSONObject();
        }

        try {
            // 文件原名称
            String fileName = file.getOriginalFilename();
            //小于1m的图片 直接上传
            OssResult result = file.getSize() < 1 * 1024 * 1024
                    ? ossHelper.upload(path, fileName, file.getBytes())
                    : ossHelper.SectionUpload(path, fileName, file.getInputStream(), 400, 5);

            if (result.isError()) {
                throw result.getException();
            }
            JSONObject data = new JSONObject();
            data.put("UploadId", result.getKey());
            data.put("Url", result.getFullUrl());
            data.put("Name", fileName);

            vh.put("code", 0);
            vh.put("data", data);
            vh.put("message", "Success");
        } catch (OSSException oe) {
            vh.put("code", -1);
            vh.put("message", "Error Code:" + oe.getErrorCode() +
                    " Request ID:      " + oe.getRequestId() +
                    " Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            vh.put("code", -1);
            vh.put("message", "Error Code:" + ce.getMessage());
        }

        return vh.toJSONObject();
    }


    /**
     * 删除文件或者文件夹
     *
     * @param file 文件夹名称或者（文件夹名称+文件名称）
     * @return
     * @throws Exception
     */
    @RequestMapping(path = "/p/cs/deleteObject", method = RequestMethod.POST)
    @ApiOperation(value = "删除文件", httpMethod = "POST")
    public JSONObject deleteObject(@RequestParam(value = "file", required = true) String file) throws Exception {
        ValueHolder vh = new ValueHolder();
        try {
            ossHelper.delete(file);
            vh.put("code", 0);
            vh.put("message", "Success");
        } catch (OSSException oe) {
            vh.put("code", -1);
            vh.put("message", "Error Code:" + oe.getErrorCode() +
                    " Request ID:      " + oe.getRequestId() +
                    " Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            vh.put("code", -1);
            vh.put("message", "Error Code:" + ce.getMessage());
        }
        return vh.toJSONObject();

    }

    /**
     * 删除文件或者文件夹
     *
     * @param folder 文件夹名称或者（文件夹名称+文件名称）
     * @return
     * @throws Exception
     */
    @RequestMapping(path = "/p/cs/deleteFolder", method = RequestMethod.POST)
    @ApiOperation(value = "删除文件夹", httpMethod = "POST")
    public JSONObject deleteFolder(@RequestParam(value = "folder", required = true) String folder) throws Exception {
        ValueHolder vh = new ValueHolder();
        try {
            ossHelper.deleteFolder(folder);
            vh.put("code", 0);
            vh.put("message", "Success");
        } catch (OSSException oe) {
            vh.put("code", -1);
            vh.put("message", "Error Code:" + oe.getErrorCode() +
                    " Request ID:      " + oe.getRequestId() +
                    " Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            vh.put("code", -1);
            vh.put("message", "Error Code:" + ce.getMessage());
        }
        return vh.toJSONObject();
    }


    /**
     * 页面上进度查询走这个方法
     *
     * @return
     */
    @RequestMapping(path = "/p/cs/uploadProgress", method = RequestMethod.POST)
    @ApiOperation(value = "文件上传进度查询", httpMethod = "POST")
    public JSONObject uploadProgress(@RequestParam(value = "uploadId", required = true) String uploadId) {
        ValueHolder vh = new ValueHolder();

        try {
            int progress = (int) ossHelper.uploadProgress(uploadId);
            if (progress < 0) {
                vh.put("code", -1);
                vh.put("message", "not found");
            } else {
                vh.put("code", 0);
                vh.put("data", progress);
            }
        } catch (Exception e) {
            vh.put("code", -1);
            vh.put("message", "Fail");
        }
        return vh.toJSONObject();
    }

}

